/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2021-2023. All rights reserved.
 * Description: UDK malloc source file
 * Author: -
 * Create: 2021.4.19
 */
#include <stdint.h>
#include <stddef.h>

#include "securec.h"
#include "udk_common.h"
#include "udk_log.h"
#include "udk_ops.h"
#include "udk_mheap.h"
#include "udk.h"

#include "udk_malloc.h"

void udk_free(void *addr)
{
    if (g_udk_reg_ops.free != NULL) {
        g_udk_reg_ops.free(addr);
        return;
    }

    if (addr == NULL) {
        return;
    }

    if (udk_malloc_heap_free(addr) != 0) {
        UDK_LOG(ERR, MALLOC, "Error: Invalid memory\n");
    }
}

void *udk_malloc_socket(size_t size, uint32_t align, int32_t socket)
{
    if (g_udk_reg_ops.malloc_socket != NULL) {
        return g_udk_reg_ops.malloc_socket(NULL, size, align, socket);
    }

    struct udk_melem melem;
    int ret;

    /* return NULL if size is 0 or alignment is not power-of-2 */
    if ((size == 0) || ((align != 0) && (udk_is_power_of_2(align) == 0))) {
        return NULL;
    }

    if (udk_malloc_heap_socket_is_external(socket) != 1 && udk_has_hugepages() == 0) {
        socket = UDK_SOCKET_ID_ANY;
    }

    ret = udk_malloc_heap_alloc(NULL, size, socket, 0, (align == 0) ? 1 : align, 0, false, &melem);
    if (ret == 0) {
        return melem.addr;
    }

    return NULL;
}

void *udk_malloc(size_t size, uint32_t align)
{
    return udk_malloc_socket(size, align, UDK_SOCKET_ID_ANY);
}

void *udk_zmalloc_socket(size_t size, uint32_t align, int32_t socket)
{
    errno_t ret;

    void *ptr = udk_malloc_socket(size, align, socket);
    if (ptr == NULL) {
        return NULL;
    }

    ret = memset_s(ptr, size, 0, size);
    if (ret != EOK) {
        udk_free(ptr);
        return NULL;
    }

    return ptr;
}

void *udk_zmalloc(size_t size, uint32_t align)
{
    return udk_zmalloc_socket(size, align, UDK_SOCKET_ID_ANY);
}

int udk_malloc_heap_socket_is_external(int socket_id)
{
    if (socket_id == UDK_SOCKET_ID_ANY) {
        return 0;
    }

    /* if there is any possibility of external memory, we should detect it */
    return -1;
}
